歡迎來到「React TDD 實戰:用 Vitest 打造可靠的前端應用」系列!
想像一下,你是一位新手開發者,剛加入一個重視程式品質的團隊。主管交給你第一個任務:「我們要建立一個 React 專案,而且要從第一天就導入測試文化。」聽起來很有挑戰性?別擔心,讓我們從最基礎的開始,一步步建立起 TDD 的基礎。
今天是我們 TDD 旅程的第一天,我們要設置 React + TypeScript + Vitest 的開發環境,並寫下第一個測試。就像學開車一樣,我們先在安全的練習場地熟悉基本操作。
今天結束後,你將學會:
第一階段:打好基礎(Day 1-10)
├── Day 01 - 環境設置與第一個測試 ★ 今天在這裡
├── ...
└── (更多精彩內容待續)
首先建立一個全新的 React 專案:
npm create vite@latest react-tdd-demo -- --template react-ts
cd react-tdd-demo
npm install
npm install -D vitest @vitest/ui jsdom
建立 vite.config.ts
:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: ['./tests/setup.ts'],
},
})
建立 tests/setup.ts
:
// 全域測試設定檔
// 這裡可以放置所有測試共用的設定
在 package.json
中新增測試指令:
{
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"test": "vitest",
"test:ui": "vitest --ui",
"coverage": "vitest run --coverage"
}
}
讓我們從最簡單的例子開始 - 一個計算機模組。
建立 tests/day01/calculator.test.ts
:
import { describe, it, expect } from 'vitest'
// 先寫測試,這時 calculator 模組還不存在
import { add } from '../../src/calculator'
describe('Calculator', () => {
it('adds two numbers correctly', () => {
const result = add(2, 3)
expect(result).toBe(5)
})
})
npm test
你會看到測試失敗的訊息,因為 calculator
模組還不存在。這就是 TDD 的「紅燈」階段 - 先寫測試,看它失敗。
建立 src/calculator.ts
:
export function add(a: number, b: number): number {
return a + b
}
再次執行測試:
npm test
現在測試應該通過了!這就是「綠燈」階段。
更新 tests/day01/calculator.test.ts
:
import { describe, it, expect } from 'vitest'
import { add, subtract, multiply, divide } from '../../src/calculator'
describe('Calculator', () => {
it('adds two numbers correctly', () => {
const result = add(2, 3)
expect(result).toBe(5)
})
it('adds negative numbers correctly', () => {
const result = add(-2, 3)
expect(result).toBe(1)
})
it('subtracts two numbers correctly', () => {
const result = subtract(5, 3)
expect(result).toBe(2)
})
it('multiplies two numbers correctly', () => {
const result = multiply(4, 3)
expect(result).toBe(12)
})
it('divides two numbers correctly', () => {
const result = divide(10, 2)
expect(result).toBe(5)
})
it('handles division by zero', () => {
const result = divide(10, 0)
expect(result).toBe(Infinity)
})
})
更新 src/calculator.ts
:
export function add(a: number, b: number): number {
return a + b
}
export function subtract(a: number, b: number): number {
return a - b
}
export function multiply(a: number, b: number): number {
return a * b
}
export function divide(a: number, b: number): number {
return a / b
}
npm test
所有測試都應該通過!
describe
: 測試套件,用來組織相關的測試it
: 個別測試案例expect
: 斷言函數,驗證結果tests/
目錄tests/day01/calculator.test.ts
).test.ts
後綴命名今天我們完成了 TDD 學習旅程的第一步!透過建立 React + TypeScript + Vitest 環境,我們學會了:
Vitest 提供多種執行測試的方式:
# 監聽模式(預設)
npm test
# 單次執行
npm run test run
# 使用 UI 介面
npm run test:ui
# 產生覆蓋率報告
npm run coverage
如果遇到「Cannot find module」錯誤,確認 tsconfig.json
的路徑設定:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}
確保測試檔案符合以下命名規則之一:
*.test.ts
*.spec.ts
tests/
目錄下如果看到 document is not defined 錯誤,確認 vite.config.ts
有設定:
test: {
environment: 'jsdom'
}
每個測試都應該遵循 AAA 模式:
試著為計算機新增以下功能:
modulo(a, b)
函數power(base, exponent)
函數💡 提示:記得先寫測試再實作功能!
今天我們成功建立了 React + TypeScript + Vitest 的測試環境,並完成了第一個單元測試。雖然例子很簡單,但我們已經體驗了完整的 TDD 流程:
記住,TDD 不只是一種測試技術,更是一種設計思維。透過先寫測試,我們被迫思考程式的介面和行為,這能幫助我們寫出更好的程式碼。
明天我們將深入了解斷言函數的威力,學習如何寫出更有表達力的測試。準備好了嗎?繼續加油! 💪